<template>
<div v-if="visabled" class="property-panel" ref="propertyPanel">
    <el-form label-suffix=":" label-position="top" :model="form" >
      <el-form-item label="节点名称">
        <el-input v-model="form.name" @input="handleNameChange"></el-input>
      </el-form-item>
      <el-form-item label="表单Key" v-if="form.$type === 'bpmn:UserTask' || form.$type === 'bpmn:StartEvent'">
        <el-input v-model="form.$attrs['camunda:formKey']" @input="handleFormKeyChange"></el-input>
      </el-form-item>
      <!-- 开始节点是否初始化发起人 -->
      <el-form-item label="使用发起人参数" v-if="form.$type === 'bpmn:StartEvent'">
        <el-switch v-model="form.$attrs['camunda:initiator']" active-value="starter" @change="handleInitiatorChange"></el-switch>       
      </el-form-item>
      <el-form-item label="指定人" v-if="form.$type === 'bpmn:UserTask'">
        <el-switch v-model="assigneeEqualsInitiator" active-text="指定为发起人" @change="handleAssigneeEqualsInitiatorChange"></el-switch>       
        <el-input v-if="!assigneeEqualsInitiator" v-model="assignee" @input="handleAssigneeChange" :readonly="assigneeReadonly" clearable="true">
          <template #append>
            <el-button @click="handleSelectUser('assignee', false)">
              <SvgIcon name="elementSearch"/>
            </el-button>
          </template>
        </el-input>
      </el-form-item>
      <el-form-item label="侯选者" v-if="form.$type === 'bpmn:UserTask'">
        <el-input v-model="candidateUsers" @input="handleCandidateUsersChange" :readonly="candidateUsersReadonly">
          <template #append>
            <el-button @click="handleSelectUser('candidateUsers', true)">
              <SvgIcon name="elementSearch"/>
            </el-button>
          </template>
        </el-input>
      </el-form-item>
      <el-form-item label="侯选组" v-if="form.$type === 'bpmn:UserTask'">
        <el-select class="w100" v-model="candidateGroups" 
          multiple placeholder=""
          @change="handleCandidateGroupsChange"
        >
          <el-option
            v-for="item in groupList"
            :key="item.code"
            :label="item.name"
            :value="item.code"
          >
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="表达式" v-if="form.$type === 'bpmn:SequenceFlow'">
        <el-input v-model="form.conditionExpression.body" @input="handleConditionExpChange"></el-input>
      </el-form-item>
      <div v-if="form.isMultiTask">
        <el-divider content-position="left">多实例设置</el-divider>
        <el-form-item label="人员清单" >
          <el-input v-model="form.multiCollection" @input="handleCollectionChange"></el-input>
        </el-form-item>
        <el-form-item label="人员循环变量" >
          <el-input v-model="form.multiElementVariable" @input="handleElementVariableChange"></el-input>
        </el-form-item> 
      </div>
      
    </el-form>
    <UserDialog ref="userDialog"></UserDialog>
  </div>
</template>
<script lang="ts">
export default {
    name: 'ModelerPropertiesPanel',
}
</script>
<script setup lang="ts">
import { onMounted, reactive, ref, toRaw, toRefs, watch, } from 'vue'
import BpmnModeler from "bpmn-js/lib/Modeler"
import UserDialog from '/@/components/vp/user/VpUserDialog.vue';
import request from '/@/utils/request';

// eslint-disable-next-line no-undef
const props = defineProps<{
    modeler: BpmnModeler
}>()

const data = reactive({
    form: {
      id: "",
      name: "",
      $type: "",
      conditionExpression:{
        body:"",
      },
      $attrs: {
        "camunda:initiator" : '',
        "camunda:formKey": '',
        "camunda:candidateGroups": '',
        "camunda:candidateUsers": '',
        "camunda:assignee": '',
      },  
      isMultiTask: false,
      multiCollection: '', //多实例-集合
      multiElementVariable: '',//多实例-循环变量               
    },
    element: null,
    groupList: [],//侯选者数据源
    assignee: '',
    candidateUsers: '',
    candidateGroups: [] as string[],
    assigneeReadonly: false,
    candidateUsersReadonly: false,
    assigneeEqualsInitiator: false,
    visabled: false,
    
})
const {visabled, form, groupList, assignee, candidateGroups, candidateUsers, assigneeReadonly, candidateUsersReadonly, assigneeEqualsInitiator} = toRefs(data);

//初始化data
const initData = ()=>{
  return {
    id: "",
    name: "",
    $type: "", 
    conditionExpression:{
        body:"",
    },   
    $attrs: {
      'camunda:initiator': '',
      "camunda:formKey": '',
      "camunda:candidateGroups": '',
      "camunda:candidateUsers": '',
      "camunda:assignee": '',
    },   
    isMultiTask: false,
    multiCollection: '', //多实例-集合
    multiElementVariable: '',//多实例-循环变量       
  }
}

onMounted(() => {
  // 监听节点选择变化
  props.modeler.on("selection.changed", (e: any) => {
    const element = e.newSelection[0];
    data.element = element
    if (!element) {
      data.visabled = false;
      return;
    }
    data.visabled = true;
    data.form = {
      ...initData(),
      ...element.businessObject,
      $attrs: element.businessObject.$attrs,
    };

    //多实例任务
    if(element.businessObject.loopCharacteristics){
      data.form.isMultiTask = true
      data.form.multiCollection = element.businessObject.loopCharacteristics.$attrs['camunda:collection']
      data.form.multiElementVariable = element.businessObject.loopCharacteristics.$attrs['camunda:elementVariable']
    }


    //改变节点初始化 指定人 选项
    let assinee = data.form.$attrs['camunda:assignee']
    data.assigneeEqualsInitiator = assinee === '${starter}'
    if(!assinee || assinee === ''){
      data.assigneeReadonly = false;
      data.assignee = "";
    }else{
      if(assinee.startsWith("${")){
        data.assigneeReadonly = false;
        data.assignee = assinee;
      }else{
        //根据 id查询姓名
        request.get(`system/user/${assinee}`).then((res)=>{
          if(res && res.data){
            data.assigneeReadonly = true;
            data.assignee = res.data.realname
          }else{
            data.assigneeReadonly = false;
            data.assignee = assinee
          }
        })
      }
    }
    //改变节点后初始化候选人 选项
    let candidateUsers = data.form.$attrs['camunda:candidateUsers']
    if(!candidateUsers || candidateUsers === ''){
      data.candidateUsersReadonly = false;
      data.candidateUsers = "";
    }else{
      if(candidateUsers.startsWith("${")){
        data.candidateUsersReadonly = false;
        data.candidateUsers = candidateUsers;
      }else{
        //根据 id查询姓名
        request.get(`system/user/many/${candidateUsers}`).then((res)=>{
          if(res && res.data && res.data.length > 0){
            data.candidateUsersReadonly = true;
            const nameArray = res.data.map((row:any)=>{
              return row.realname;
            })
            data.candidateUsers = nameArray.join(",")
          }else{
            data.assigneeReadonly = false;
            data.assignee = candidateUsers
          }
        })
      }
    }
    //改变节点后初始化 侯选组 选项
    let candidateGroups = data.form.$attrs['camunda:candidateGroups']
    if(!candidateGroups || candidateGroups === ''){
      data.candidateGroups = [] as string[];
    }else{
      data.candidateGroups = candidateGroups.split(",");
    }
  });

  //  监听节点属性变化
  props.modeler.on("element.changed", (e: any) => {
    const { element } = e;
    if (!element) return;
    //  新增节点需要更新回属性面板
    if (element.id === data.form.id) {
      data.form.name = element.businessObject.name;
      if(element.businessObject.$type==='bpmn:UserTask'){
        if(!element.businessObject.loopCharacteristics && data.form.isMultiTask){
            data.form.isMultiTask = false
        }
        if (element.businessObject.loopCharacteristics && !data.form.isMultiTask){
          data.form.isMultiTask = true
          data.form.multiCollection = ""
          data.form.multiElementVariable = ""
        }
      }

      
    }
  });

  //加载侯选组选项清单
  request.get("/workflow/candidate/group/list").then((res) => {
    data.groupList = res?.data || [];
  });
})


//节点名称变更更新到modeler
const handleNameChange = (name: string)=>{
  const modeling = props.modeler.get("modeling");
  modeling.updateLabel(toRaw(data.element), name);
}

//开始节点初始化发起人开关变更时更新到modeler
const handleInitiatorChange = (flag: boolean)=>{
  const modeling = props.modeler.get("modeling");
  modeling.updateProperties(toRaw(data.element), {
    "camunda:initiator": flag?"starter":""
  });
}

const handleFormKeyChange = (formKey: string)=>{
  const modeling = props.modeler.get("modeling");
  modeling.updateProperties(toRaw(data.element), {
    "camunda:formKey": formKey,
  })
}


//选择用户弹窗
const userDialog = ref();
//Assign 打开选择人员弹窗
const handleSelectUser = (type: string, multi: boolean) => {
  userDialog.value.handleOpen({
      type: 1, // 1、选择人员t_user 2、选择档案b_p3_001
      multi: multi,    // 是否多选
      callback: (obj: any) => {
          if(type =='assignee'){
            let userId = obj.yhid;
            let userName = obj.xm;
            const modeling = props.modeler.get("modeling");
            modeling.updateProperties(toRaw(data.element), {
              "camunda:assignee": userId,
            })
            
            data.form.$attrs['camunda:assignee'] = userId;
            data.assignee = userName;
            if(!userId){
              data.assigneeReadonly = false;
            }else{
              data.assigneeReadonly = true;
            }
          } else if(type =='candidateUsers'){
            let userIds = "";
            let userNames = "";
            if(obj && obj.length > 0){
              const userIdsArray = obj.map((row: any)=>{
                return row.yhid;
              })
              userIds = userIdsArray.join(",");
              const userNamesArray = obj.map((row: any)=>{
                return row.xm;
              })
              userIds = userIdsArray.join(",");
              userNames = userNamesArray.join(",")
            }
            const modeling = props.modeler.get("modeling");
            modeling.updateProperties(toRaw(data.element), {
              "camunda:candidateUsers": userIds,
            })
            
            data.form.$attrs['camunda:candidateUsers'] = userIds;
            data.candidateUsers = userNames;
            if(!userIds){
              data.candidateUsersReadonly = false;
            }else{
              data.candidateUsersReadonly = true;
            }
          }  
      }
  });
}
//选择用户回调
const handleUserSelected = (obj: any)=>{
  if(obj.type==='assignee'){
    let userId = "";
    let userName = "";
    if(obj.data && obj.data.length > 0){
      userId = obj.data[0].id;
      userName = obj.data[0].realname;
    }
    const modeling = props.modeler.get("modeling");
    modeling.updateProperties(toRaw(data.element), {
      "camunda:assignee": userId,
    })
    
    data.form.$attrs['camunda:assignee'] = userId
    data.assignee = userName
    if(userId === ''){
      data.assigneeReadonly = false;
    }else{
      data.assigneeReadonly = true;
    }
  } else if(obj.type==='candidateUsers'){
    let userIds = "";
    let userNames = "";
    if(obj.data && obj.data.length > 0){
      const userIdsArray = obj.data.map((row: any)=>{
        return row.id;
      })
      userIds = userIdsArray.join(",");
      const userNamesArray = obj.data.map((row: any)=>{
        return row.realname;
      })
      userIds = userIdsArray.join(",");
      userNames = userNamesArray.join(",")
    }
    const modeling = props.modeler.get("modeling");
    modeling.updateProperties(toRaw(data.element), {
      "camunda:candidateUsers": userIds,
    })
    
    data.form.$attrs['camunda:candidateUsers'] = userIds
    data.candidateUsers = userNames
    if(userIds === ''){
      data.candidateUsersReadonly = false;
    }else{
      data.candidateUsersReadonly = true;
    }
  }
}
//assignee手工输入时事件
const handleAssigneeChange = (val: string)=>{
  data.assignee = val.trim();
  const modeling = props.modeler.get("modeling");
  modeling.updateProperties(toRaw(data.element), {
    "camunda:assignee": data.assignee,
  })
}

//指定人  指定为发起人时将指定人数据改为${starter}
const handleAssigneeEqualsInitiatorChange = (flag: boolean) =>{
  if(flag){
    const modeling = props.modeler.get("modeling");
    modeling.updateProperties(toRaw(data.element), {
      "camunda:assignee": '${starter}',
    })
    data.assignee='${starter}'
    data.form.$attrs['camunda:assignee']='${starter}'
  }
}
//candidateUsers手工输入时事件
const handleCandidateUsersChange = (val: string)=>{
  data.candidateUsers = val.trim();
  const modeling = props.modeler.get("modeling");
  modeling.updateProperties(toRaw(data.element), {
    "camunda:candidateUsers": data.candidateUsers,
  })
}
//candidateGroups变更更新modeler
const handleCandidateGroupsChange = (val:any)=>{
  const modeling = props.modeler.get("modeling");
  modeling.updateProperties(toRaw(data.element), {
    "camunda:candidateGroups": val.join(","),
  })
}

//表达式变更事件
const handleConditionExpChange = (val: string)=>{
  const modeling = props.modeler.get("modeling");
  const moddle = props.modeler._moddle;
  const conditionExp = moddle.create('bpmn:FormalExpression', {
    body: val,
  })
  modeling.updateProperties(toRaw(data.element), {
    "bpmn:conditionExpression": conditionExp,
  })
}
/**
 * 多实例-集合变更事件
 * @param val 
 */
const handleCollectionChange = (val: string)=>{
  const modeling = props.modeler.get("modeling");
  const moddle = props.modeler._moddle;
  const conditionExp = moddle.create('bpmn:MultiInstanceLoopCharacteristics', {
    "camunda:collection" : val,
    "camunda:elementVariable": data.form.multiElementVariable,
  })
  modeling.updateProperties(toRaw(data.element), {
    "loopCharacteristics": conditionExp,
  })
}

/**
 * 多实例-循环亦是变更事件
 * @param val 
 */
const handleElementVariableChange = (val: string)=>{
  const modeling = props.modeler.get("modeling");
  const moddle = props.modeler._moddle;
  const conditionExp = moddle.create('bpmn:MultiInstanceLoopCharacteristics', {
    "camunda:collection" : data.form.multiCollection,
    "camunda:elementVariable": val,
  })
  modeling.updateProperties(toRaw(data.element), {
    "loopCharacteristics": conditionExp,
  })
}

</script>
<style scoped lang="scss">
.property-panel {
  position: absolute;
  background-color: var(--el-bg-color);
  right: 0px;
  top: 0px;
  // bottom: 0px;
  padding: 4px;
  width: 300px;
  height: 100%;
  overflow-y: auto;
}
</style>